package com.stylefeng.guns.modular.flagglory.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.stylefeng.guns.common.persistence.model.*;
import com.stylefeng.guns.common.persistence.dao.QuestionMapper;
import com.stylefeng.guns.core.base.tips.SuccessTip;
import com.stylefeng.guns.core.exception.FrontException;
import com.stylefeng.guns.modular.flagglory.dao.QuestionDao;
import com.stylefeng.guns.modular.flagglory.service.*;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * lg_题库 服务实现类
 * </p>
 *
 * @author xin123
 * @since 2018-01-30
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements IQuestionService {
    @Autowired
    private QuestionDao questionDao;
    @Autowired
    private IQuestionCategoryService questionCategoryService;
    @Autowired
    private ISeasonService seasonService;
    @Autowired
    private IAnswerMirrorService answerMirrorService;
    @Autowired
    private ISettingService settingService;
    @Autowired
    private IGloryUserService userService;
    @Autowired
    private IDepartmentService departmentService;
    @Autowired
    private IDivisionService divisionService;
    @Autowired
    private IQuestionService questionService;
    @Autowired
    private IRobotService robotService;
    @Autowired
    private ILevelService levelService;
    private final static Integer QUESTION_NUMBER = 5;

    public Question selectRandomQuestionByCategoryId(Integer categoryId, List<Integer> idList) {
        return questionDao.selectRandomQuestion(categoryId, idList);
    }

    public Question selectRandomQuestion(List<Integer> idList) {
        return questionDao.selectRandomQuestion(null, idList);
    }

    public JSONArray getProportionRandomQuestionArray(Integer questionNumber) throws FrontException {
        List<QuestionCategory> questionCategories = questionCategoryService.selectList(null);
        //全部题目的集合
        Integer allProportion = 0;
        //首先计算总比重
        for (QuestionCategory category : questionCategories) {
            Integer proportion = category.getProportion();
            allProportion += proportion;
        }
        //比重数组
        BigDecimal[] proportions = new BigDecimal[questionCategories.size()];
        BigDecimal nowProportion = new BigDecimal(0);
        //计算比重数组
        for (int i = 0; i < questionCategories.size(); i++) {
            QuestionCategory category = questionCategories.get(i);
            BigDecimal p = new BigDecimal(category.getProportion() * 1.0 / allProportion).setScale(2, BigDecimal.ROUND_HALF_UP);
            nowProportion = nowProportion.add(p);
            proportions[i] = nowProportion;
        }
        //问题json集合
        JSONArray questionArray = new JSONArray();
        List<Integer> idList = new ArrayList<>();
        for (int num = 0; num < questionNumber; num++) {
            //根据比重计算随机的分类
            QuestionCategory nowCate = null;
            double random = Math.random();
            for (int i = 0; i < proportions.length; i++) {
                if (random < proportions[i].doubleValue()) {
                    nowCate = questionCategories.get(i);
                    break;
                }
            }
            if (null != nowCate) {
                Question question = selectRandomQuestion(idList);
                if (null == question) {
                    throw new FrontException(501, "题库不足！");
                }
                JSONObject questionJson = JSON.parseObject(question.getInfo());
                questionJson.put("questionCategoryName", nowCate.getName());
                questionJson.put("questionCategoryId", nowCate.getId());
                questionJson.put("questionId", question.getId());
                questionArray.add(questionJson);
                idList.add(question.getId());
            }
        }
        return questionArray;
    }

    public JSONArray getRandomQuestionArray(Integer questionNumber) throws FrontException {
        JSONArray questionArray = new JSONArray();
        List<Integer> idList = new ArrayList<>();
        for (int num = 0; num < questionNumber; num++) {
            Question question = selectRandomQuestion(idList);
            if (null == question) {
                throw new FrontException(501, "题库不足！");
            }
            JSONObject questionJson = JSON.parseObject(question.getInfo());
            Integer categoryid = question.getCategoryid();
            QuestionCategory category = questionCategoryService.selectById(categoryid);
            questionJson.put("questionCategoryName", category.getName());
            questionJson.put("categoryId", category.getId());
            questionJson.put("questionId", question.getId());
            questionArray.add(questionJson);
            idList.add(question.getId());
        }
        return questionArray;
    }

    public JSONObject getQuestionInfo(Integer userId, Integer divisionId) throws Exception {
        Season defaultSeason = seasonService.getDefaultSeason();
        EntityWrapper<AnswerMirror> mirrorEntityWrapper = new EntityWrapper<>();
        mirrorEntityWrapper.where("seasonid=" + defaultSeason.getId()).and("divisionid=" + divisionId).and("used=0").and("userid!=" + userId);
        //如果有镜像 就用镜像，不然用机器人
        AnswerMirror randomAnswerMirror = answerMirrorService.getRandomAnswerMirror(defaultSeason.getId(), divisionId, userId);
        if (randomAnswerMirror == null) {
            return getRobotQuestionInfo(userId, divisionId);
        }else{
            GloryUser user = userService.selectById(randomAnswerMirror.getUserid());
            if(user == null){
                //删除该镜像
                randomAnswerMirror.deleteById();
                return getRobotQuestionInfo(userId, divisionId);
            }
        }
        JSONObject data = new JSONObject();
        JSONObject userInfo = getUserInfo(userId);
        JSONObject opponent = new JSONObject();
        JSONObject opponentInfo = getUserInfo(randomAnswerMirror.getUserid());
        JSONArray answerInfo = new JSONArray();
        JSONArray questions = new JSONArray();
        JSONArray answers = JSONObject.parseArray(randomAnswerMirror.getAnswerinfo());
        for (int i = 0; i < answers.size(); i++) {
            JSONObject infoDto = answers.getJSONObject(i).getJSONObject("infoDto");
            //添加答案信息
            JSONObject answer = new JSONObject();
            answer.put("rightAnswer", infoDto.getInteger("rightAnswer"));
            answer.put("answer", infoDto.getInteger("selected"));
            answer.put("time", infoDto.getString("time"));
            answerInfo.add(answer);
            //添加题目信息
            JSONObject question = new JSONObject();
            question.put("answers", infoDto.getJSONArray("answers"));
            question.put("rightAnswer", infoDto.getInteger("rightAnswer"));
            question.put("infoText", infoDto.getString("infoText"));
            question.put("questionId", answers.getJSONObject(i).getInteger("questionId"));
            Integer categoryId = answers.getJSONObject(i).getInteger("categoryId");
            question.put("categoryId", categoryId);
            QuestionCategory category = questionCategoryService.selectById(categoryId);
            question.put("questionCategoryName", category.getName());
            questions.add(question);
        }
        opponent.put("answerInfo", answerInfo);
        opponent.put("isRobot", false);
        opponent.put("opponentInfo", opponentInfo);

        data.put("userInfo", userInfo);
        data.put("opponent", opponent);
        data.put("questions", questions);
        randomAnswerMirror.setUsed(true);
        answerMirrorService.updateById(randomAnswerMirror);
        Division division = divisionService.selectById(divisionId);
        data = updateFlag(data, userInfo, division.getFlag(), userId);
        return data;
    }

    public JSONObject getRobotQuestionInfo(Integer userId, Integer divisionId) throws Exception {
        JSONObject data = new JSONObject();
        JSONArray questionArray = questionService.getRandomQuestionArray(QUESTION_NUMBER);
        data.put("questions", questionArray);
        JSONObject userInfo = getUserInfo(userId);
        data.put("userInfo", userInfo);

        //放入机器人信息
        EntityWrapper<Division> divisionEntityWrapper = new EntityWrapper<>();
        divisionEntityWrapper.where("id=" + divisionId);
        Division robotDivision = divisionService.selectOne(divisionEntityWrapper);
        if (null == robotDivision) {
            throw new FrontException(501, "该段位不存在！匹配失败！");
        }
        EntityWrapper<Robot> robotEntityWrapper = new EntityWrapper<>();
        robotEntityWrapper.where("divisionid=" + robotDivision.getId());
        int count = robotService.selectCount(robotEntityWrapper);
        Robot robot = null;
        if (count > 1) {
            robot = robotService.getRadomRobot(robotDivision.getId());
        } else {
            robot = robotService.selectOne(robotEntityWrapper);
        }
        if (null == robot) {
            throw new FrontException(501, "匹配不到该段位的用户！");
        }
        JSONObject opponent = new JSONObject();
        opponent.put("isRobot", true);
        JSONObject opponentInfo = new JSONObject();
        opponentInfo.put("nickname", robot.getNickname());
        opponentInfo.put("realname", robot.getNickname());
        opponentInfo.put("avatarUrl", robot.getHeadimgurl());
        Integer robotLevelId = robot.getLevel();
        Level robotLevel = levelService.selectById(robotLevelId);
        if (null != robotLevel) {
            opponentInfo.put("level", robotLevel.getName());
        }
        opponentInfo.put("division", robotDivision.getName());
       /* BigDecimal robotWinRate = new BigDecimal(0);
        if (robot.getTotal() >= 1) {
            BigDecimal winB = new BigDecimal(robot.getWin());
            BigDecimal totalB = new BigDecimal(robot.getTotal());
            robotWinRate = winB.divide(totalB, 2,BigDecimal.ROUND_HALF_EVEN);
            robotWinRate = robotWinRate.multiply(new BigDecimal(100));
        }*/
        opponentInfo.put("winRate", robot.getRate() +  "%");
        //计算机器人答案
        double robotRate = robot.getRate() * 1.0 / 100;
        JSONArray answerInfo = new JSONArray();
        for (int i = 0; i < questionArray.size(); i++) {
            JSONObject answerJson = new JSONObject();
            JSONObject question = questionArray.getJSONObject(i);
            Integer rightAnswer = question.getInteger("rightAnswer");
            answerJson.put("rightAnswer", rightAnswer);
            double random = Math.random();
            if (random <= robotRate) {
                //如果正确，就设置正确答案
                answerJson.put("answer", rightAnswer);
            } else {
                //如果错误，随机筛选一个错误答案
                JSONArray answers = question.getJSONArray("answers");
                int errorNum = (int) (Math.random() * 10);
                Integer errorAnswer = errorNum % answers.size();
                answerJson.put("answer", errorAnswer);
            }
            Integer maxtime = robot.getMaxtime();
            Integer mintime = robot.getMintime();
            answerJson.put("time", Math.round(random * (maxtime - mintime) + mintime));
            answerInfo.add(answerJson);
        }
        opponent.put("opponentInfo", opponentInfo);
        opponent.put("answerInfo", answerInfo);

        data.put("opponent", opponent);
        Integer divisionFlag = robotDivision.getFlag();
        data = updateFlag(data, userInfo, divisionFlag, userId);
        return data;
    }

    private JSONObject updateFlag(JSONObject data, JSONObject userInfo, Integer divisionFlag, Integer userId) throws Exception {
        Integer userFlag = userInfo.getInteger("userFlag");
        if (userFlag < divisionFlag) {
            throw new FrontException(501, "用户旗帜不足" + divisionFlag + "！匹配失败！");
        }
        settingService.getQuestionSetting(data);
        userFlag = userFlag - divisionFlag;
        GloryUser user = userService.selectById(userId);
        user.setFlag(userFlag);
        user.updateById();
        return data;
    }

    private JSONObject getUserInfo(Integer userId) throws FrontException {
        Map<String, Object> map = userService.selectGloryUserInfo(userId);
        if (null == map) {
            throw new FrontException(501, "当前用户不存在！匹配失败！");
        }
        String nickname = map.getOrDefault("nickname", "").toString();
        String realname = map.getOrDefault("realname", "").toString();
        String level = map.getOrDefault("levelName", "").toString();
        String avatarUrl = map.getOrDefault("avatarUrl", "avatarUrl").toString();
        int userFlag = Integer.parseInt(map.getOrDefault("flag", 0).toString());

        int stars = Integer.parseInt(map.getOrDefault("stars", 0).toString());
        Division division = divisionService.getDivision(stars);
        int deptid = Integer.parseInt(map.getOrDefault("deptid", 0).toString());
        Department department = departmentService.selectById(deptid);
        String from = "";
        if (null != department) {
            Department pDepartment = departmentService.selectById(department.getPid());
            from = department.getFullname();
            if (null != pDepartment) {
                from = pDepartment.getFullname() + from;
            }
        }
        int total = Integer.parseInt(map.getOrDefault("total", 0).toString());
        int win = Integer.parseInt(map.getOrDefault("win", 0).toString());
        BigDecimal winRate = new BigDecimal(0);
        if (total > 1) {
            BigDecimal winB = new BigDecimal(win);
            BigDecimal totalB = new BigDecimal(total);
            winRate = winB.divide(totalB, 2,BigDecimal.ROUND_HALF_EVEN);
            winRate = winRate.multiply(new BigDecimal(100));
        }
        //放入用户信息
        JSONObject userInfo = new JSONObject();
        userInfo.put("nickname", nickname);
        userInfo.put("realname", realname);
        userInfo.put("userId", userId);
        userInfo.put("level", level);
        userInfo.put("division", division.getName());
        userInfo.put("userFlag", userFlag);
        userInfo.put("divisionId", division.getId());
        userInfo.put("from", from);
        userInfo.put("winRate", winRate.intValue() + "%");
        userInfo.put("avatarUrl", avatarUrl);
        return userInfo;
    }
}
